import os
import yaml
import git
import tarfile
import time
import shutil
import logging
import argparse
import multiprocessing
from concurrent.futures import ThreadPoolExecutor,wait,ALL_COMPLETED

logging.basicConfig(level = logging.INFO, format = '%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger()


def init_source_dir(source_dir):
    if not os.path.exists(source_dir):
        os.mkdir(source_dir)

def init_repo(remote, source_dir, repo_path):
    try:
        logger.info("fetch... {}".format(repo_path))
        repo_dir = os.path.join(source_dir, repo_path)
        try:
            repo = git.Repo(repo_dir)
            remote = repo.remote("origin")
        except:
            repo = git.Repo.init(repo_dir)
            remote = repo.create_remote("origin", remote)

        remote.fetch()
        logger.info("fetch {} finished".format(repo_path))
    except Exception as e:
        logger.error(e)
    
def make_targz(output_filename, source_dir):
    """
    一次性打包目录为tar.gz
    :param output_filename: 压缩文件名
    :param source_dir: 需要打包的目录
    :return: bool
    """
    try:
        with tarfile.open(output_filename, "w:gz") as tar:
            tar.add(source_dir, arcname=os.path.basename(source_dir))

        return True
    except Exception as e:
        logger.error(e)
        return False

def init_args():
    """
    init args
    :return:
    """
    parser = argparse.ArgumentParser()
    parser.add_argument("-to_dir", type=str, dest="to_dir", default="source", required=False)

    return parser.parse_args()

args = init_args()

init_source_dir(args.to_dir)

with open('repolist.yaml','r') as f:
    data = yaml.load(f, yaml.Loader)

logger.info("now fetch upstream source code")
start_time = time.time()
cpu_count = multiprocessing.cpu_count()
with ThreadPoolExecutor(max_workers = cpu_count) as t:
    all_task = []
    for item in data['projects']:
        all_task.append(t.submit(init_repo, item["path"], os.path.join(args.to_dir,"src"), item["name"]))
    wait(all_task, return_when = ALL_COMPLETED)
end_time = time.time()
logger.info("fetch upstream source code finished, duration time {}".format(end_time - start_time))

if os.path.exists(os.path.join(args.to_dir, "src") + "_bak.tar.gz"):
    os.remove(os.path.join(args.to_dir, "src") + "_bak.tar.gz")

# add source to tar.gz
logger.info("add {}_bak.tar.gz processing".format(os.path.join(args.to_dir,"src")))
start_time = time.time()
isOk = make_targz(os.path.join(args.to_dir, "src") + "_bak.tar.gz", os.path.join(args.to_dir, "src"))
if isOk:
    end_time = time.time()
    logger.info("add src.tar.gz successful, duration time {}".format(end_time - start_time))
else:
    logger.info("add src.tar.gz faild")

shutil.move(os.path.join(args.to_dir, "src") + "_bak.tar.gz", os.path.join(args.to_dir, "src") + ".tar.gz")